package com.stox.client.ui.javafx.chartingy.model.shape;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.Label;
import javafx.scene.shape.Line;

import com.stox.client.ui.javafx.chartingy.model.chart.Chart;
import com.stox.shared.util.Constant;

public class HorizontalRay extends Shape {

	private final ControlPoint staticControlPoint;
	private final ControlPoint dynamicControlPoint;
	private final Label valueLabel = new Label();
	private final Line line = new Line();

	public HorizontalRay(final Chart<?, ?> chart, final double initialSceneX, final double initialSceneY) {
		super(chart);
		staticControlPoint = new ControlPoint(chart, initialSceneX, initialSceneY);
		dynamicControlPoint = new ControlPoint(chart, initialSceneX, initialSceneY);

		line.startYProperty().bindBidirectional(line.endYProperty());
		line.startYProperty().bindBidirectional(staticControlPoint.centerYProperty());
		staticControlPoint.centerYProperty().bindBidirectional(dynamicControlPoint.centerYProperty());
		staticControlPoint.centerYProperty().bindBidirectional(deletePoint.centerYProperty());

		line.startXProperty().bind(staticControlPoint.centerXProperty());
		deletePoint.centerXProperty().bind(line.endXProperty().subtract(deletePoint.radiusProperty()));
		valueLabel.layoutXProperty().bind(chart.getValueAxis().layoutXProperty());
		valueLabel.layoutYProperty().bind(staticControlPoint.centerYProperty().subtract(valueLabel.heightProperty().divide(2)));
		staticControlPoint.centerYProperty().addListener(new ChangeListener<Number>() {
			@Override
			public void changed(final ObservableValue<? extends Number> observable, final Number oldValue, final Number newValue) {
				valueLabel.setText(Constant.numberFormat.format(chart.getValueAxis().getValueForDisplay(newValue.doubleValue())));
			}
		});

		line.setEndX(chart.getChartContentArea().getWidth());

		final ChangeListener<Number> directionListener = new ChangeListener<Number>() {

			private boolean right = true;

			@Override
			public void changed(final ObservableValue<? extends Number> observable, final Number oldValue, final Number newValue) {
				if ((dynamicControlPoint.getCenterX() >= staticControlPoint.getCenterX()) && !right) {
					line.endXProperty().unbind();
					deletePoint.centerXProperty().unbind();
					deletePoint.centerXProperty().bind(line.endXProperty().subtract(deletePoint.radiusProperty()));
					line.setEndX(chart.getChartContentArea().getWidth());
					line.endXProperty().bind(chart.getChartContentArea().widthProperty());
					right = true;
				} else if ((dynamicControlPoint.getCenterX() < staticControlPoint.getCenterX()) && right) {
					line.endXProperty().unbind();
					deletePoint.centerXProperty().unbind();
					deletePoint.centerXProperty().bind(line.endXProperty().add(deletePoint.radiusProperty()));
					line.setEndX(chart.getChartContentArea().getLayoutX());
					line.endXProperty().bind(chart.getChartContentArea().layoutXProperty());
					right = false;
				}
			}
		};

		dynamicControlPoint.centerXProperty().addListener(directionListener);
		staticControlPoint.centerXProperty().addListener(directionListener);

		staticControlPoint.setCenterY(chart.getChartContentArea().sceneToLocal(initialSceneX, initialSceneY).getY());

		getChildren().addAll(staticControlPoint, dynamicControlPoint, line, deletePoint, valueLabel);
	}

	public ControlPoint getDynamicControlPoint() {
		return dynamicControlPoint;
	}

	@Override
	public void update() {
		staticControlPoint.update();
		dynamicControlPoint.update();
	}

}
